package com.allen.app.common.config.redis.redisson;

import com.allen.app.common.config.aspect.DistributedLockAspect;
import com.allen.app.common.config.redis.RedissonProperties;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.redisson.spring.cache.CacheConfig;
import org.redisson.spring.cache.RedissonSpringCacheManager;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.CollectionUtils;

@Slf4j
@EnableCaching
@Configuration
@ConditionalOnClass(name = "org.redisson.config.Config")
@EnableConfigurationProperties(RedissonProperties.class)
public class RedissonAutoConfiguration {

    @Bean(destroyMethod = "shutdown")
    @ConditionalOnMissingBean
    @ConditionalOnProperty(name = {RedissonProperties.PREFIX + ".server-mode", RedissonProperties.PREFIX + ".addresses"})
    public RedissonClient redissonClient(RedissonProperties properties) {
        log.info("\t===>>\tRedissonClient initializing......");
        return RedissonUtils.createClient(properties);
    }

    @Bean
    @ConditionalOnBean(RedissonClient.class)
    @ConditionalOnMissingBean(CacheManager.class)
    public CacheManager redissonCacheManager(RedissonClient redissonClient, RedissonProperties properties) {
        RedissonSpringCacheManager cacheManager = new RedissonSpringCacheManager(redissonClient);
        Map<String, CacheConfig> cacheConfigs = properties.getCaches();
        if (!CollectionUtils.isEmpty(cacheConfigs)) {
            cacheManager.setConfig(cacheConfigs);
        }
        log.info("\t===>>\tCacheManager initializing......");
        return cacheManager;
    }

    @Bean
    @ConditionalOnBean(RedissonClient.class)
    public DistributedLockAspect distributedLockAspect(RedissonClient redissonClient) {
        log.info("\t===>>\tdistributedLockAspect initializing......");
        return new DistributedLockAspect(redissonClient);
    }
}
